import { VantComponent } from "../common/component";
import { range } from "../common/utils";
import { isObj } from "../common/validator";
const DEFAULT_DURATION = 200;
VantComponent({
	classes: ["active-class"],
	props: {
		valueKey: String,
		className: String,
		itemHeight: Number,
		visibleItemCount: Number,
		initialOptions: {
			type: Array,
			value: []
		},
		defaultIndex: {
			type: Number,
			value: 0,
			observer(value) {
				this.setIndex(value);
			}
		}
	},
	data: {
		startY: 0,
		offset: 0,
		duration: 0,
		startOffset: 0,
		options: [],
		currentIndex: 0
	},
	created() {
		const { defaultIndex, initialOptions } = this.data;
		this.set({
			currentIndex: defaultIndex,
			options: initialOptions
		}).then(() => {
			this.setIndex(defaultIndex);
		});
	},
	methods: {
		getCount() {
			return this.data.options.length;
		},
		onTouchStart(event) {
			this.setData({
				startY: event.touches[0].clientY,
				startOffset: this.data.offset,
				duration: 0
			});
		},
		onTouchMove(event) {
			const { data } = this;
			const deltaY = event.touches[0].clientY - data.startY;
			this.setData({
				offset: range(data.startOffset + deltaY, -(this.getCount() * data.itemHeight), data.itemHeight)
			});
		},
		onTouchEnd() {
			const { data } = this;
			if (data.offset !== data.startOffset) {
				this.setData({ duration: DEFAULT_DURATION });
				const index = range(Math.round(-data.offset / data.itemHeight), 0, this.getCount() - 1);
				this.setIndex(index, true);
			}
		},
		onClickItem(event) {
			const { index } = event.currentTarget.dataset;
			this.setIndex(index, true);
		},
		adjustIndex(index) {
			const { data } = this;
			const count = this.getCount();
			index = range(index, 0, count);
			for (let i = index; i < count; i++) {
				if (!this.isDisabled(data.options[i])) return i;
			}
			for (let i = index - 1; i >= 0; i--) {
				if (!this.isDisabled(data.options[i])) return i;
			}
		},
		isDisabled(option) {
			return isObj(option) && option.disabled;
		},
		getOptionText(option) {
			const { data } = this;
			return isObj(option) && data.valueKey in option ? option[data.valueKey] : option;
		},
		setIndex(index, userAction) {
			const { data } = this;
			index = this.adjustIndex(index) || 0;
			const offset = -index * data.itemHeight;
			if (index !== data.currentIndex) {
				return this.set({ offset, currentIndex: index }).then(() => {
					userAction && this.$emit("change", index);
				});
			}
			return this.set({ offset });
		},
		setValue(value) {
			const { options } = this.data;
			for (let i = 0; i < options.length; i++) {
				if (this.getOptionText(options[i]) === value) {
					return this.setIndex(i);
				}
			}
			return Promise.resolve();
		},
		getValue() {
			const { data } = this;
			return data.options[data.currentIndex];
		}
	}
});
